package com.qiniu.githubdata.job;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
public class GitHubScraperService {

    private static final Map<String, String> COLOR_MAP = new HashMap<>();
//            Collections.singletonMap(
//        "0", "#ebedf0",
//        "1", "#9be9a8",
//        "2", "#40c463",
//        "3", "#30a14e",
//        "4", "#216e39"
//    );
    //init
    static {
        COLOR_MAP.put("0", "#ebedf0");
        COLOR_MAP.put("1", "#9be9a8");
        COLOR_MAP.put("2", "#40c463");
        COLOR_MAP.put("3", "#30a14e");
        COLOR_MAP.put("4", "#216e39");
    }

//    @Async("githubTaskExecutor")
    public CompletableFuture<Map<String, Object>> fetchContributions(String username, String format) {
        try {
            String url = String.format("https://github.com/users/%s/contributions", username);
            Document doc = Jsoup.connect(url)
                    .header("Accept", "application/json")
                    .header("Accept-Encoding", "gzip, deflate")
                    .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
                    .get();

            Elements contributionDays = doc.select("td.ContributionCalendar-day");
            List<Map<String, Object>> contributions = new ArrayList<>();
            int totalContributions = 0;

            for (Element day : contributionDays) {
                String date = day.attr("data-date");
                if (date.isEmpty()) continue;
                
                String dataCount = day.attr("data-count");
                int count = Integer.parseInt(dataCount);
                String level = day.attr("data-level");
                String color = COLOR_MAP.getOrDefault(level, "#ebedf0");
                
                Map<String, Object> contribution = new HashMap<>();
                contribution.put("date", date);
                contribution.put("count", count);
                contribution.put("color", color);
                contribution.put("level", level);
                
                contributions.add(contribution);
                totalContributions += count;
            }

            Map<String, Object> result = new HashMap<>();
            result.put("totalContributions", totalContributions);
            
            if ("nested".equals(format)) {
                result.put("contributions", convertToNestedFormat(contributions));
            } else {
                result.put("contributions", contributions);
            }
            return CompletableFuture.completedFuture(result);
            
        } catch (IOException e) {
            return CompletableFuture.completedFuture( Collections.singletonMap("error", e.getMessage()));
        }
    }

    private Map<String, Map<String, Map<String, Map<String, Object>>>> convertToNestedFormat(
            List<Map<String, Object>> contributions) {
        Map<String, Map<String, Map<String, Map<String, Object>>>> nested = new TreeMap<>();
        
        for (Map<String, Object> contrib : contributions) {
            String date = (String) contrib.get("date");
            String[] dateParts = date.split("-");
            String year = dateParts[0];
            String month = dateParts[1];
            String day = dateParts[2];
            
            nested.computeIfAbsent(year, k -> new TreeMap<>())
                 .computeIfAbsent(month, k -> new TreeMap<>())
                 .put(day, contrib);
        }
        
        return nested;
    }
}